package com.ap.core.email.message.translator.impl;


import com.ap.core.cxf.email.jaxb.managemessage.DataMapInfoType;
import com.ap.core.cxf.email.jaxb.managemessage.SendEmail1Request;
import com.ap.core.email.api.EmailPayloadInfo;
import com.ap.core.email.api.impl.DefaultEmailPayloadInfo;
import com.ap.core.email.message.translator.api.InfoTranslator;
import com.ap.core.email.velocity.VelocityResourceNotFoundException;
import com.ap.core.exception.BusinessFailureException;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.ui.velocity.VelocityEngineUtils;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * Implementation class for {@link InfoTranslator}
 */
public class EmailInfoTranslator implements InfoTranslator<SendEmail1Request, EmailPayloadInfo> {

    private final static String VELOCITY_TEMPLATE_PROPERTIES = "velocity_template.properties";
    private final static String PARTICIPANT_VELOCITY_TEMPLATE_PROPERTIES = "participant_velocity_template.properties";
    private final static String TITLE = "title";
    private final static String HIGH_PRIORITY = "high_priority";

    private VelocityEngine velocityEngine;
    private String encoding;


    @Override
    public EmailPayloadInfo translate(SendEmail1Request boundObject){
        final EmailPayloadInfo emailPayloadInfo = new DefaultEmailPayloadInfo(getAsStringArray(boundObject.getTo()),
                                                                              boundObject.getFrom(),
                                                                              getAsStringArray(boundObject.getCC()),
                                                                              getAsStringArray(boundObject.getBCC()));

        //Velocity Template stuff
        Map<String, Object> model = new HashMap<String, Object>();

        for (DataMapInfoType dataMapInfoType : boundObject.getDataMap()) {
            model.put(dataMapInfoType.getName(), dataMapInfoType.getValue());
        }

        emailPayloadInfo.setTitle((String) model.get(TITLE));
        emailPayloadInfo.setHighPriority(getHighPriority(model.get(HIGH_PRIORITY)));

        String templatePath = getTemplatePathString (boundObject);

        final String genericBodyContent = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, templatePath, encoding, model);
        emailPayloadInfo.setGenericBodyContent(genericBodyContent);

        return emailPayloadInfo;
    }

    private String getTemplatePathString(SendEmail1Request boundObject) {
        Properties properties = new Properties();
        String templatePath = null;

        if (null != boundObject.getTemplateName()) {

            try {
                properties.load(this.getClass().getClassLoader().getResourceAsStream(VELOCITY_TEMPLATE_PROPERTIES));
            } catch (IOException e) {
                throw new VelocityResourceNotFoundException("Not able to find template properties file = " + VELOCITY_TEMPLATE_PROPERTIES + "from classpath", e);
            }
            templatePath = properties.getProperty(boundObject.getTemplateName().name());
        }else {
            // get Participant id and type mapping for getting corresponding template
            try{
                properties.load(this.getClass().getClassLoader().getResourceAsStream(PARTICIPANT_VELOCITY_TEMPLATE_PROPERTIES));
            } catch (IOException e) {
                throw new VelocityResourceNotFoundException("Not able to find template properties file = " + PARTICIPANT_VELOCITY_TEMPLATE_PROPERTIES + "from classpath", e);
            }
            String lookUpKey = boundObject.getParticipantType().name() + "_" + boundObject.getParticipantId();
            templatePath = properties.getProperty(lookUpKey);
        }
        return templatePath;
    }

    public void setVelocityEngine(VelocityEngine velocityEngine) {
        this.velocityEngine = velocityEngine;
    }

    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

    private String[] getAsStringArray(List<String> listOfObjects){
        return listOfObjects == null || listOfObjects.isEmpty() ? null : listOfObjects.toArray(new String[listOfObjects.size()]);
    }

    private boolean getHighPriority(Object param) {
        boolean highPriority = false;
        if (param != null) {
            if (param instanceof Boolean) {
                highPriority = (Boolean) param;
            } else if (param instanceof String) {
                String parseMe = (String) param;
                if ("true".equals(parseMe.toLowerCase())) {
                    highPriority = Boolean.TRUE;
                }
            }
        }
        return highPriority;
    }
}
